package com.cindata

import grails.converters.JSON
import grails.transaction.Transactional
import groovy.transform.CompileStatic
import groovy.transform.TypeChecked

import java.security.MessageDigest
import java.text.SimpleDateFormat

import com.cindata.dictionary.*

@Transactional
@CompileStatic
@TypeChecked
class CollateralService
{
    static scope = "singleton"

    CollateralFlowStageService collateralFlowStageService
    CollateralFlowStageConditionService collateralFlowStageConditionService
    CollateralFlowStageEventService collateralFlowStageEventService
    CollateralFlowStageRoleService collateralFlowStageRoleService
    CollateralFlowStageNotificationService collateralFlowStageNotificationService

    // 初始化押品登记流程
    def initCollateralFlowStage(Collateral collateral, Workflow workflow = null)
    {
        if (!workflow)
        {
            def account = collateral?.createBy?.account
            workflow = AccountFlow.find("from AccountFlow where account.id = ? and type.id = ?", [account?.id, collateral.type?.id])?.workflow
        }

        if (workflow)
        {
            collateralFlowStageService.initFlowStage(collateral, workflow)
            collateralFlowStageConditionService.initFlowStageCondition(collateral, workflow)
            collateralFlowStageEventService.initFlowStageEvent(collateral, workflow)
            collateralFlowStageRoleService.initFlowStageRole(collateral, workflow)
            collateralFlowStageNotificationService.initFlowStageNotification(collateral, workflow)

            def flowFirstStage = WorkflowStage.find("from WorkflowStage where workflow.id = ? order by executionSequence asc", [workflow?.id])
            def collateralFlowStage = CollateralFlowStage.find("from CollateralFlowStage where collateral.id = ? and stage.id = ? order by executionSequence asc", [collateral?.id, flowFirstStage?.stage.id])
            if (collateralFlowStage)
            {
                collateralFlowStage.startTime = new Date()
                collateralFlowStage.save flush: true

                collateral.stage = (CollateralStage) flowFirstStage?.stage
                collateral.status = "Pending"
                collateral.save flush: true
            }
        }
        else
        {
            println "未找到工作流，押品 ${collateral?.externalId} 初始化失败"
        }
    }

    // 推进
    def approve(Collateral collateral)
    {
        def map = [:]

        def currentFlowStage = CollateralFlowStage.find("from CollateralFlowStage where collateral.id = ? and stage.id = ? order by executionSequence asc", [collateral?.id, collateral?.stage.id])

        // 事件
        collateralFlowStageEventService.evaluate(currentFlowStage, "negative")

        // 验证
        def verifyCondition = collateralFlowStageConditionService.evaluate(collateral)
        if (!verifyCondition['flag'])
        {
            return verifyCondition
        }

        // 事件
        collateralFlowStageEventService.evaluate(currentFlowStage, "positive")

        def nextFlowStage = CollateralFlowStage.find("from CollateralFlowStage where collateral.id = ? and executionSequence > ? order by executionSequence asc", [collateral?.id, currentFlowStage?.executionSequence])
        if (!nextFlowStage)
        {
            map['flag'] = false
            map['message'] = "找不到工作流"
            return map
        }

        // 如果 nextFlowStage 为工作流的最后一个阶段，则将 nextFlowStage endTime 赋值成当前时间,将押品状态赋值成 Completed
        def lastFlowStage = CollateralFlowStage.find("from CollateralFlowStage where collateral.id = ? and executionSequence > ? order by executionSequence asc", [collateral?.id, nextFlowStage?.executionSequence])

        currentFlowStage.endTime = new Date()
        currentFlowStage.processed = true
        currentFlowStage.save flush: true

        nextFlowStage.startTime = new Date()
        if (!lastFlowStage)
        {
            nextFlowStage.endTime = new Date()
            collateral.status = "Completed"
        }
        nextFlowStage.save flush: true

        collateral.stage = (CollateralStage) nextFlowStage?.stage
        collateral.save flush: true

        // 短信
        // collateralFlowStageNotificationService.sendNotification(collateral)

        map['flag'] = true
        map['message'] = "成功"
        return map
    }

    // 拒绝
    Boolean reject(Collateral collateral)
    {
        def flag = false
        if (collateral?.status == "Pending")
        {
            def currentFlowStage = CollateralFlowStage.find("from CollateralFlowStage where collateral.id = ? and stage.id = ? order by executionSequence asc", [collateral?.id, collateral?.stage?.id])
            if (currentFlowStage?.canReject)
            {
                def previousFlowStage = CollateralFlowStage.find("from CollateralFlowStage where collateral.id = ? and executionSequence < ? and processed = true order by executionSequence desc", [collateral?.id, currentFlowStage?.executionSequence])
                if (previousFlowStage)
                {
                    collateral.stage = (CollateralStage) previousFlowStage.stage
                    if (collateral.validate())
                    {
                        collateral.save flush: true

                        //发送消息
                        // collateralFlowStageNotificationService.sendNotification(collateral)

                        flag = true
                    }
                    else
                    {
                        collateral.errors.each {
                            log.info "${it}"
                        }
                    }
                }
            }
        }
        flag
    }
}
